package com.tangdi.production.mpaychl.controller.third;


import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.tangdi.production.mpaychl.service.impl.kuaiqian.Pkipair;
import com.tangdi.production.mpbase.constants.ExcepCode;
import com.tangdi.production.mpbase.constants.MsgCT;
import com.tangdi.production.mpbase.exception.BusinessException;
import com.tangdi.production.mpbase.service.OrderService;
import com.tangdi.production.mpbase.util.ObjectUtil;
import com.tangdi.production.tdbase.util.ServletUtil;


/**
 * 快钱支付回调接口定义
 * @author HarryNie
 *
 */
@Controller
@RequestMapping("/third/")
public class KuaiQianController {
	
	private static Logger log = LoggerFactory.getLogger(KuaiQianController.class);
	
	@Autowired
	private OrderService orderService;
	

	/**
	 * 平安支付支付回调
	 * @param request
	 * @return
	 */
	@RequestMapping(value="kuaiqian/payCallBack")
	@ResponseBody
	public String payCallBack(HttpServletRequest request,HttpServletResponse response) throws Exception{
		//获取请求参数列表
		log.info("进入【块钱支付】【支付回调】..."); 
		String returnUrl = "";
		try {
			Map<String, Object> reqMap = ServletUtil.getReqMap(request);
			log.info("[块钱支付]支付回调:" + reqMap);
			Map<String,String> paramMap = new HashMap<String,String>();
			for (String  key: reqMap.keySet()) {
				paramMap.put(key, ObjectUtil.getString(reqMap.get(key)));
			}
			
			returnUrl = (String)paramMap.get("ext1");
			
			if(paramMap == null || paramMap.isEmpty()){
				throw new BusinessException(ExcepCode.EX900000,"请求内容为空");
			}
			
			//订单号
			String prdOrdNo = (String)paramMap.get("orderId");
			if(StringUtils.isEmpty(prdOrdNo)){
				throw new BusinessException(ExcepCode.EX900000,"回调订单号为空");
			}
			
			Map<String,Object> queryMap = new HashMap<String,Object>();
			queryMap.put("prdOrdNo", prdOrdNo);
			Map<String,Object> prdOrdMap = orderService.getPrdOrdMap(queryMap);
			
			String ordStatus = (String)prdOrdMap.get("ordStatus");
			if(MsgCT.ORDSTATUS_SUCCESS.equals(ordStatus)){//成功的订单不允许再更新
				log.warn("订单状态已成功，不允许更新...");
				returnSuccess(response,returnUrl);
				return null;
			}
			
			//原交易大商户编号
//			String mchNo = (String)prdOrdMap.get("TMERCID");
//			String mchNo = "10140";
//			if(StringUtils.isEmpty(mchNo)){
//				throw new BusinessException(ExcepCode.EX900000,"原交易商户号不能为空");
//			}
			
			// 根据渠道号 商户号获得商户密钥
			queryMap.clear();
//			queryMap.put("orgNo", prdOrdMap.get("payChannel"));//交易渠道编号
//			queryMap.put("routeMerId", mchNo);//渠道商户编号
//			List<Map<String,Object>> routeList = orderService.getOrgInfo(queryMap);
//			if(routeList == null || routeList.isEmpty()){
//				throw new BusinessException(ExcepCode.EX900001,"路由查询为空");
//			}
//			Map<String,Object> routeMap = routeList.get(0);
//			
//			//商户密钥
//			String merKey = (String)routeMap.get("merKey");
//			String merKey = "7386072b1f94fdd7acaae83cd0f0f1c1";
//			if(StringUtils.isEmpty(merKey)){
//				throw new BusinessException(ExcepCode.EX900000,"商户密钥为空,无法验签");
//			}
			
			boolean verify = verifySign(request);
			if(!verify){
				log.error("签名验证失败 ");
				throw new BusinessException(ExcepCode.EX900000,"签名验证失败");
			}
			log.info("---------------payCallBack----验签成功----------------------------");
			//定义回调订单信息Map
			Map<String,Object> orderCallBackMap = new HashMap<String, Object>();
			orderCallBackMap.put("prdOrdNo", prdOrdNo);//订单号
			orderCallBackMap.put("ordStatus", MsgCT.ORDSTATUS_PROCESSING);
			String status = (String)paramMap.get("payResult"); //订单状态（1交易成功，2待支付，9待输入密码，4已取消）
			
			// 判断订单状态
			if ("10".equals(status)) {//支付成功
				orderCallBackMap.put("ordStatus", MsgCT.ORDSTATUS_SUCCESS);
//			}else if("2".equals(status)){
//				orderCallBackMap.put("ordStatus", MsgCT.ORDSTATUS_PROCESSING);
//			}else if("9".equals(status)){
//				orderCallBackMap.put("ordStatus", MsgCT.ORDSTATUS_PROCESSING);
//			}else if("4".equals(status)){
//				orderCallBackMap.put("ordStatus", MsgCT.ORDSTATUS_CANCELED);
			}else{//其他情况不处理
				log.warn("回调状态不明确,不处理...");
				returnFailure(response);
				return null;
			}
			
			//调用回调更新订单
			log.info("通知平台更新订单[{}]",orderCallBackMap);
			orderService.prdPayCallBack(orderCallBackMap);
		}catch (Exception e) {
			log.error(e.getMessage(),e);
			returnFailure(response);
			return null;
		}
		log.info("【块钱支付】【消费回调】完成" );
		returnSuccess(response,returnUrl);
		return null;
	}
	
	public boolean verifySign(HttpServletRequest request){
		//人民币网关账号，该账号为11位人民币网关商户编号+01,该值与提交时相同。
		String merchantAcctId = request.getParameter("merchantAcctId");
		//网关版本，固定值：v2.0,该值与提交时相同。
		String version = request.getParameter("version");
		//语言种类，1代表中文显示，2代表英文显示。默认为1,该值与提交时相同。
		String language = request.getParameter("language");
		//签名类型,该值为4，代表PKI加密方式,该值与提交时相同。
		String signType = request.getParameter("signType");
		//支付方式，一般为00，代表所有的支付方式。如果是银行直连商户，该值为10,该值与提交时相同。
		String payType = request.getParameter("payType");
		//银行代码，如果payType为00，该值为空；如果payType为10,该值与提交时相同。
		String bankId = request.getParameter("bankId");
		//商户订单号，该值与提交时相同。
		String orderId = request.getParameter("orderId");
		//订单提交时间，格式：yyyyMMddHHmmss，如：20071117020101,该值与提交时相同。
		String orderTime = request.getParameter("orderTime");
		//订单金额，金额以“分”为单位，商户测试以1分测试即可，切勿以大金额测试,该值与支付时相同。
		String orderAmount = request.getParameter("orderAmount");
		// 快钱交易号，商户每一笔交易都会在快钱生成一个交易号。
		String dealId = request.getParameter("dealId");
		//银行交易号 ，快钱交易在银行支付时对应的交易号，如果不是通过银行卡支付，则为空
		String bankDealId = request.getParameter("bankDealId");
		//快钱交易时间，快钱对交易进行处理的时间,格式：yyyyMMddHHmmss，如：20071117020101
		String dealTime = request.getParameter("dealTime");
		//商户实际支付金额 以分为单位。比方10元，提交时金额应为1000。该金额代表商户快钱账户最终收到的金额。
		String payAmount = request.getParameter("payAmount");
		//费用，快钱收取商户的手续费，单位为分。
		String fee = request.getParameter("fee");
		//扩展字段1，该值与提交时相同。
		String ext1 = request.getParameter("ext1");
		//扩展字段2，该值与提交时相同。
		String ext2 = request.getParameter("ext2");
		//处理结果， 10支付成功，11 支付失败，00订单申请成功，01 订单申请失败
		String payResult = request.getParameter("payResult");
		//错误代码 ，请参照《人民币网关接口文档》最后部分的详细解释。
		String errCode = request.getParameter("errCode");
		//签名字符串 
		String signMsg = request.getParameter("signMsg");
		String merchantSignMsgVal = "";
		merchantSignMsgVal = appendParam(merchantSignMsgVal,"merchantAcctId", merchantAcctId);
		merchantSignMsgVal = appendParam(merchantSignMsgVal, "version",version);
		merchantSignMsgVal = appendParam(merchantSignMsgVal, "language",language);
		merchantSignMsgVal = appendParam(merchantSignMsgVal, "signType",signType);
		merchantSignMsgVal = appendParam(merchantSignMsgVal, "payType",payType);
		merchantSignMsgVal = appendParam(merchantSignMsgVal, "bankId",bankId);
		merchantSignMsgVal = appendParam(merchantSignMsgVal, "orderId",orderId);
		merchantSignMsgVal = appendParam(merchantSignMsgVal, "orderTime",orderTime);
		merchantSignMsgVal = appendParam(merchantSignMsgVal, "orderAmount",orderAmount);
		merchantSignMsgVal = appendParam(merchantSignMsgVal, "dealId",dealId);
		merchantSignMsgVal = appendParam(merchantSignMsgVal, "bankDealId",bankDealId);
		merchantSignMsgVal = appendParam(merchantSignMsgVal, "dealTime",dealTime);
		merchantSignMsgVal = appendParam(merchantSignMsgVal, "payAmount",payAmount);
		merchantSignMsgVal = appendParam(merchantSignMsgVal, "fee", fee);
		merchantSignMsgVal = appendParam(merchantSignMsgVal, "ext1", ext1);
		merchantSignMsgVal = appendParam(merchantSignMsgVal, "ext2", ext2);
		merchantSignMsgVal = appendParam(merchantSignMsgVal, "payResult",payResult);
		merchantSignMsgVal = appendParam(merchantSignMsgVal, "errCode",errCode);
		Pkipair pki = new Pkipair();
		if (signMsg.indexOf(" ")!=-1) {
			signMsg = signMsg.replaceAll(" ", "+");
		}
		boolean flag = pki.enCodeByCer(merchantSignMsgVal, signMsg);
		return flag;
	}
	
	public String appendParam(String returns, String paramId, String paramValue) {
		if (!returns.equals("")) {

			if (!paramValue.equals("")) {
				returns += "&" + paramId + "=" + paramValue;
			}

		} else {

			if (!paramValue.equals("")) {
				returns = paramId + "=" + paramValue;
			}
		}

		return returns;
	}
	
	/**
	 * 返回成功
	 * 
	 * @param response
	 * @param obj
	 * @throws Exception
	 */
	private void returnSuccess(HttpServletResponse response,String returnUrl) throws Exception {
		respContent(response, "<result>1</result><redirecturl>"+returnUrl+"</redirecturl>");
	}

	/**
	 * 返回失败
	 * 
	 * @param response
	 * @param obj
	 * @throws Exception
	 */
	private void returnFailure(HttpServletResponse response) throws Exception {
		respContent(response, "FAILURE");
	}

	private void respContent(HttpServletResponse response, String content)
			throws Exception {
		PrintWriter out = response.getWriter();
		out.write(content);
		out.flush();
		out.close();
	}

	public static void main(String[] args) {
//		String str = "transaction_id=20180710162429100505, amount=10.0000, datetime=20180710162714, orderid=1531211019836, returncode=00, sign=D35EFDE5C90F5F9EC3063314F0ABBA35, attach=1, memberid=10140";
//		Map<String,String> paramMap = new HashMap<String,String>();
//		for (String s : str.split(",")) {
//			String[] sz = s.split("=");
//			paramMap.put(sz[0].trim(), sz[1]);
//		}
////		paramMap.put("remark", "授予,frompartyid:null,fromaccountnumber:990305001001");
//		
//		
//		boolean verify = SignByMD5.verify(paramMap, "jwhxurovfsa8ecatelnr862vpr2sk6fg");
//		System.out.println(verify);
		
	}
	
}
